/*******************************************************************************
  * 文件：StateMachine.h
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2021.01.14
  * 说明：面向对象的状态机
*******************************************************************************/
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H
    
/* 头文件 *********************************************************************/
#include "Macro.h"
#include "Constant.h"
#include "Typedefine.h"
#include "OS_Timer.h"
#include "Debug.h"

/* 宏定义 *********************************************************************/
// 状态机DEBUG宏定义
#define  STATE_MACHINE_DEBUG

// 状态表初始化宏定义
#define  STATE_MACHINE_STATE(state, next_state, time, handler)          \
                            {state, next_state, time, #state, handler}

/* 类型定义 *******************************************************************/
enum
{   
    STATE_CTRL_HOLD  = 1,    //保持当前状态
    STATE_CTRL_NEXT  = 2,    //切换至下一状态
    STATE_CTRL_RETRY = 3,    //重试当前状态
};// 状态机函数执行之后的退出返回值

/* 变量声明 *******************************************************************/
typedef struct
{
    S16 State;              //当前状态
    S16 NextState;          //下次状态
    U16 Time;               //定时时间
    const char *Name;       //状态名称
    U32 (*pfStateHandler)(void); //状态机处理函数
}StateMachineOps_ts;//状态机操作

typedef struct
{
    S16 LastState;          //上次状态
    S16 CurState;           //当前状态
    U16 RetryCnt;           //重试次数
    S16 SMOpsCount;         //状态机操作表元素个数
    const char *SMName;     //状态机名称
    const StateMachineOps_ts *FirstSMOp;//状态表首元素指针
    const StateMachineOps_ts *CurSMOp;  //当前状态的操作指针
    Timer_ts sTimer;        //定时器
}StateMachine_ts;//状态机

/* 函数声明 *******************************************************************/
S16 StateMachine_GetLastState(StateMachine_ts *psStateMachine);         // 获取上次状态
S16 StateMachine_GetCurState(StateMachine_ts *psStateMachine);          // 获取当前状态
U16 StateMachine_GetRetryCount(StateMachine_ts *psStateMachine);        // 获取重试次数
const char* StateMachine_GetCurStateName(StateMachine_ts *psStateMachine);// 获取当前状态名称
void StateMchine_ChangeLastState(StateMachine_ts *psStateMachine);      // 切换至上次状态
void StateMachine_Change(StateMachine_ts* psStateMachine,S16 state);    // 状态切换
void StateMachine_Recover(StateMachine_ts *psStateMachine,S16 state);   // 状态恢复
void StateMchine_Init(StateMachine_ts* psStateMachine,
                      const char*SMName,
                      const StateMachineOps_ts *SMOpts,
                      S16 SMOptCount);                                  // 状态机初始化
#endif
